package com.xinggq.user.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinggq.common.context.UserContext;
import com.xinggq.common.enums.EnableEnum;
import com.xinggq.common.exception.AbstractCommonException;
import com.xinggq.common.page.PageCondition;
import com.xinggq.common.utils.IdGenerator;
import com.xinggq.common.utils.Validate;
import com.xinggq.user.api.exception.UserCenterException;
import com.xinggq.user.service.dto.tenant.TenantQueryRequest;
import com.xinggq.user.service.dto.tenant.TenantVO;
import com.xinggq.user.service.entity.SysTenantEntity;
import com.xinggq.user.service.mapper.SysTenantMapper;
import com.xinggq.user.service.service.TenantService;
import com.xinggq.user.service.service.UserInfoService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
 * 租户服务实现类
 *
 * @author xinggq
 * @since 2025-01-26
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TenantServiceImpl
    extends ServiceImpl<SysTenantMapper, SysTenantEntity> implements TenantService {

  private final SysTenantMapper tenantMapper;
  private final UserInfoService userInfoService;


  @Override
  public SysTenantEntity getById(Long id) {
    if (id == null) {
      throw new IllegalArgumentException("租户ID不能为空");
    }

    SysTenantEntity tenant = tenantMapper.selectById(id);
    if (tenant == null || EnableEnum.D.getCode().equals(tenant.getStatus())) {
      return null;
    }
    return tenant;
  }

  @Override
  public SysTenantEntity getByTenantCode(String tenantCode) {
    if (!StringUtils.hasText(tenantCode)) {
      throw new IllegalArgumentException("租户编码不能为空");
    }

    LambdaQueryWrapper<SysTenantEntity> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(SysTenantEntity::getTenantCode, tenantCode)
        .ne(SysTenantEntity::getStatus, EnableEnum.D.getCode());

    return tenantMapper.selectOne(wrapper);
  }

  @Override
  public IPage<TenantVO> page(PageCondition<TenantQueryRequest> request) {
    LambdaQueryWrapper<SysTenantEntity> wrapper = new LambdaQueryWrapper<>();
    TenantQueryRequest queryParam = request.getQueryDto();
    // 排除已删除的租户
    wrapper.ne(SysTenantEntity::getStatus, EnableEnum.D.getCode());
    if (queryParam != null) {
      // 租户名称模糊查询
      if (StringUtils.hasText(queryParam.tenantName())) {
        wrapper.like(SysTenantEntity::getTenantName, queryParam.tenantName());
      }
      // 租户名称模糊查询
      if (StringUtils.hasText(queryParam.tenantCode())) {
        wrapper.like(SysTenantEntity::getTenantCode, queryParam.tenantCode());
      }
      // 状态查询
      if (queryParam.status() != null) {
        wrapper.eq(SysTenantEntity::getStatus, queryParam.status());
      }
    }
    // 按创建时间倒序
    wrapper.orderByDesc(SysTenantEntity::getCreatedAt);
    Page<SysTenantEntity> pageResult = this.page(
        new Page<>(request.getPageNum(), request.getPageSize()), wrapper);
    return pageResult.convert(TenantVO::fromEntity);
  }

  @Override
  public List<SysTenantEntity> listActive() {
    LambdaQueryWrapper<SysTenantEntity> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(SysTenantEntity::getStatus, EnableEnum.Y.getCode())
        .orderByAsc(SysTenantEntity::getTenantName);

    return tenantMapper.selectList(wrapper);
  }

  @Override
  public SysTenantEntity create(SysTenantEntity tenant) {
    Validate.objectNotNull(tenant, "租户信息不能为空");

    // 验证必填字段
    validateTenantForCreate(tenant);

    // 检查租户编码是否已存在
    if (existsByTenantCode(tenant.getTenantCode())) {
      throw UserCenterException.dataExists("租户编码");
    }

    tenant.setId(IdGenerator.generateId());
    tenant.setCreateInfo(UserContext.getCurrentUserId());
    tenant.setStatus(EnableEnum.Y.getCode());

    // 设置默认值
    if (tenant.getMaxUsers() == null) {
      tenant.setMaxUsers(100);
    }
    // 创建租户
    tenantMapper.insert(tenant);
    // 创建租户的初始化用户
    userInfoService.initTenantAdmin(tenant);

    log.info("创建租户成功，租户ID: {}, 租户编码: {}", tenant.getId(), tenant.getTenantCode());

    return tenant;
  }

  @Override
  public SysTenantEntity update(SysTenantEntity tenant) {
    if (tenant == null || tenant.getId() == null) {
      throw new IllegalArgumentException("租户ID不能为空");
    }

    // 检查租户是否存在
    SysTenantEntity existingTenant = getById(tenant.getId());
    if (existingTenant == null) {
      throw AbstractCommonException.dataNotFound("租户");
    }

    // 验证必填字段
    validateTenantForUpdate(tenant);

    // 检查租户编码是否已被其他租户使用
    if (StringUtils.hasText(tenant.getTenantCode()) &&
        existsByTenantCode(tenant.getTenantCode(), tenant.getId())) {
      throw AbstractCommonException.dataExists("租户编码");
    }

    // 设置更新信息
    tenant.setUpdateInfo(UserContext.getCurrentUserId());

    tenantMapper.updateById(tenant);
    log.info("更新租户成功，租户ID: {}", tenant.getId());

    return getById(tenant.getId());
  }

  @Override
  public boolean deleteById(Long id) {
    if (id == null) {
      throw new IllegalArgumentException("租户ID不能为空");
    }
    SysTenantEntity tenant = getById(id);
    if (tenant == null) {
      throw AbstractCommonException.dataNotFound("租户");
    }

    // 逻辑删除
    SysTenantEntity updateTenant = new SysTenantEntity();
    updateTenant.setId(id);
    updateTenant.setStatus(EnableEnum.D.getCode());
    updateTenant.setUpdateInfo(UserContext.getCurrentUserId());

    int result = tenantMapper.updateById(updateTenant);
    if (result > 0) {
      log.info("删除租户成功，租户ID: {}", id);
      return true;
    }
    return false;
  }

  @Override
  public boolean enable(Long id) {
    return updateStatus(id, EnableEnum.Y.getCode(), "启用");
  }

  @Override
  public boolean disable(Long id) {
    return updateStatus(id, EnableEnum.N.getCode(), "禁用");
  }

  @Override
  public boolean existsByTenantCode(String tenantCode) {
    return existsByTenantCode(tenantCode, null);
  }

  @Override
  public boolean existsByTenantCode(String tenantCode, Long excludeId) {
    if (!StringUtils.hasText(tenantCode)) {
      return false;
    }

    LambdaQueryWrapper<SysTenantEntity> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(SysTenantEntity::getTenantCode, tenantCode)
        .ne(SysTenantEntity::getStatus, EnableEnum.D.getCode());

    if (excludeId != null) {
      wrapper.ne(SysTenantEntity::getId, excludeId);
    }

    return tenantMapper.selectCount(wrapper) > 0;
  }

  /**
   * 更新租户状态
   */
  private boolean updateStatus(Long id, int status, String operation) {
    if (id == null) {
      throw new IllegalArgumentException("租户ID不能为空");
    }

    SysTenantEntity tenant = getById(id);
    if (tenant == null) {
      throw AbstractCommonException.dataNotFound("租户");
    }

    SysTenantEntity updateTenant = new SysTenantEntity();
    updateTenant.setId(id);
    updateTenant.setStatus(status);
    updateTenant.setUpdateInfo(UserContext.getCurrentUserId());

    int result = tenantMapper.updateById(updateTenant);
    if (result > 0) {
      log.info("{}租户成功，租户ID: {}", operation, id);
      return true;
    }
    return false;
  }

  /**
   * 验证租户创建时的必填字段
   */
  private void validateTenantForCreate(SysTenantEntity tenant) {
    if (!StringUtils.hasText(tenant.getTenantName())) {
      throw new IllegalArgumentException("租户名称不能为空");
    }
    if (!StringUtils.hasText(tenant.getTenantCode())) {
      throw new IllegalArgumentException("租户编码不能为空");
    }
  }

  /**
   * 验证租户更新时的必填字段
   */
  private void validateTenantForUpdate(SysTenantEntity tenant) {
    if (StringUtils.hasText(tenant.getTenantName()) && tenant.getTenantName().trim().isEmpty()) {
      throw new IllegalArgumentException("租户名称不能为空");
    }
    if (StringUtils.hasText(tenant.getTenantCode()) && tenant.getTenantCode().trim().isEmpty()) {
      throw new IllegalArgumentException("租户编码不能为空");
    }
  }
}